{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 变量声明\n",
    "\n",
    "```ebnf\n",
    "AmbientVariableDeclaration ::= <\"var\"> ws Identifier [TypeAnnotation] [ws-opt <';'>]\n",
    "TypeAnnotation ::= ws-opt <':'> ws Type\n",
    "// 类型定义\n",
    "Type ::= TypeLiteral\n",
    "       | TypeReference\n",
    "       | TypeQuery\n",
    "       (*| PredefinedType*)\n",
    "\n",
    "TypeLiteral ::= ObjectType\n",
    "              | ArrayType\n",
    "              | FunctionType\n",
    "              | ConstructorType\n",
    "\n",
    "TypeReference ::= QualifiedIdentifier [ws-opt TypeArguments]\n",
    "\n",
    "       QualifiedIdentifier ::= Identifier\n",
    "                            | ModuleName <'.'> Identifier\n",
    "       // 任意 变量名\n",
    "       Identifier ::= #\"[$_\\p{L}][$_\\p{L}\\p{N}]*\"\n",
    "\n",
    "TypeQuery ::= <\"typeof\"> ws QualifiedIdentifier\n",
    "\n",
    "// 预定义类型\n",
    "(*PredefinedType ::= \"any\"\n",
    "                 | \"never\"\n",
    "                 | \"void\"\n",
    "                 | \"null\"\n",
    "                 | \"undefined\"\n",
    "                     | \"symbol\"\n",
    "                     | \"bigint\"\n",
    "                 | \"number\"\n",
    "                 | \"boolean\"\n",
    "                 | \"string\"\n",
    "                 | \"object\"\n",
    "                 | \"unknown\"*)\n",
    "\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "{\n",
    "    // 简单变量声明\n",
    "    /* VariableDeclaration */var /* SyntaxList */ /* Identifier */_a;\n",
    "    var _b/* ExclamationToken */! /* TypeLiteral */: number;\n",
    "    /* VariableDeclarationList */var _c = 2, _d = _c;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "// 解构变量声明\n",
    "{\n",
    "  const /* ObjectBindingPattern */ { a = 1, ...bc }: { a: number, b: number, c: number } = { a: 1, b: 2, c: 3 };\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- var let const\n",
    "  var: 函数作用域\n",
    "  let, const: 块作用域\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "{\n",
    "    let x = <const>\"hello\";\n",
    "    // const断言\n",
    "    const a = 1 as const;\n",
    "    //    ^?\n",
    "    const b = { name: \"\" } as const;\n",
    "    //    ^?\n",
    "    const f = function <const T>(arg: T) { } as const;\n",
    "    //    ^?\n",
    "}\n",
    "{\n",
    "    // const 断言 参数 5.0 新增\n",
    "    type HasNames = { names: string[] };\n",
    "    function getNamesExactly<const T extends /* satisfies */HasNames>(arg: T): T[\"names\"] {\n",
    "        //                       ^^^^^\n",
    "        return arg.names;\n",
    "    }\n",
    "    // Inferred type: readonly [\"Alice\", \"Bob\", \"Eve\"]\n",
    "    // Note: Didn't need to write 'as const' here\n",
    "    const names = getNamesExactly({ names: [\"Alice\", \"Bob\", \"Eve\"] });\n",
    "\n",
    "    function getNamesExactlyNoConst<T extends HasNames>(arg: T): T[\"names\"] {\n",
    "        //                  ^^^^^^^\n",
    "        return arg.names;\n",
    "    }\n",
    "    // Inferred type: readonly [\"Alice\", \"Bob\", \"Eve\"]\n",
    "    // Note: Didn't need to write 'as const' here\n",
    "    const namesAsConst = getNamesExactly({ names: [\"Alice\", \"Bob\", \"Eve\"] });\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[ \u001b[33m2\u001b[39m, \u001b[33m1\u001b[39m ]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 解构\n",
    "{\n",
    "    type O = { a: number, b: number, c?: number };\n",
    "\n",
    "    const o: O = { a: 1, b: 2 };\n",
    "\n",
    "    // 属性重命名\n",
    "    const { ...oRename } = o;\n",
    "\n",
    "    // 默认值, 仅当 c === undefined 时生效\n",
    "    let { a, b, c = 10 } = o;\n",
    "    c === 10;\n",
    "\n",
    "    // 交换变量\n",
    "    [a, b] = [b, a];\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "// ts的类型是 type-annotation\n",
    "// 相关: https://github.com/tc39/proposal-type-annotations;  **type annotations are treated as comments. **\n",
    "let x: number;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "所有的在代码中 (最基本) 能出现类型 的地方 (不包括计算(keyof))\n",
    "\n",
    "1. comment 注释\n",
    "\n",
    "   `JSDOC`\n",
    "\n",
    "2. type-string 字符串类型\n",
    "\n",
    "   `\"\"` 或 `''` 或 <code>``</code> 或\n",
    "\n",
    "3. numeric-literal 数字字面量\n",
    "\n",
    "   `1` 或 `1n` 或 `1e3` 或 `2_00` 或 `0x1` 或 `0o1` 或 `1.2` 或 `NaN`\n",
    "\n",
    "4. type-primitive 基元类型\n",
    "\n",
    "   `string|number|boolean|bigint|symbol|any|void|never|unknown` 9 种\n",
    "\n",
    "5. type-builtin-literals 内建字面量\n",
    "\n",
    "   `this|true|false|undefined|null|object` 6 种\n",
    "\n",
    "6. type-parameters 泛型参数\n",
    "\n",
    "   `<T>`\n",
    "\n",
    "7. type-tuple 元组类型\n",
    "\n",
    "   `[T]` 或 `[...T]` 或 `[arg: T]`\n",
    "\n",
    "8. type-object 对象类型\n",
    "\n",
    "   `{}` 或 `{...a}` 或 `{(): void}`\n",
    "\n",
    "9. type-operators 类型操作符\n",
    "\n",
    "   `{} | {}` 或 `{} & {}`\n",
    "\n",
    "10. type-conditional 条件类型\n",
    "\n",
    "    `T extends U ? T ? U`\n",
    "\n",
    "11. type-fn-type-parameters 函数类型参数\n",
    "\n",
    "    `abstract new () => T`\n",
    "\n",
    "12. type-paren-or-function-parameters 括号类型或函数参数类型\n",
    "\n",
    "    `(number | string)` 或 `(arg: number): boolean` \n",
    "\n",
    "    <!-- 或 `public|private|protected|readonly a` -->\n",
    "\n",
    "13. type-function-return-type 函数返回值类型\n",
    "\n",
    "    `asserts a is T`\n",
    "\n",
    "类型前面也可能出现 readonly 修饰符"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "codemirror_mode": "typescript",
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nbconvert_exporter": "script",
   "pygments_lexer": "typescript",
   "version": "5.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
